use clap::Parser;
use std::sync::Arc;
use tokio::net::TcpListener;
use tracing::{info, error};

mod server;
mod protocol;
mod storage;
mod commands;
mod config;

use config::Config;
use server::Server;
use storage::Storage;

#[derive(Parser)]
#[command(name = "minidis")]
#[command(about = "A single-node Redis server implementation in Rust")]
struct Args {
    /// Server configuration file
    #[arg(short, long, default_value = "minidis.conf")]
    config: String,

    /// Server port
    #[arg(short, long, default_value = "6379")]
    port: u16,

    /// Server address
    #[arg(short, long, default_value = "127.0.0.1")]
    addr: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize tracing
    tracing_subscriber::fmt::init();

    let args = Args::parse();

    // Load configuration
    let mut config = Config::load(&args.config).unwrap_or_else(|_| {
        info!("Using default configuration");
        Config::default()
    });

    // Override config with command line arguments if provided
    let addr = format!("{}:{}",
        if args.addr != "127.0.0.1" { args.addr } else { config.bind.clone() },
        if args.port != 6379 { args.port } else { config.port }
    );

    info!("Starting Minidis server on {}", addr);

    // Create storage engine
    let storage = Arc::new(Storage::new());

    // Create and start server
    let server = Server::new(storage, config);
    server.start(&addr).await?;

    Ok(())
}
